package com.ljdemo.lrecorder.activity

import android.Manifest
import android.content.ContentValues
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.media.projection.MediaProjectionManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.os.FileUtils
import android.provider.MediaStore
import android.provider.Settings
import android.util.Log
import android.webkit.ConsoleMessage
import android.webkit.JavascriptInterface
import android.webkit.ValueCallback
import android.webkit.WebChromeClient
import android.webkit.WebView
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import com.google.gson.Gson
import com.ljdemo.lrecorder.R
import com.ljdemo.lrecorder.been.VideoInfo
import com.ljdemo.lrecorder.model.Timer
import com.ljdemo.lrecorder.service.ScreenRecordService
import com.ljdemo.lrecorder.utils.AlertUtil
import com.ljdemo.lrecorder.utils.AppUtil
import com.ljdemo.lrecorder.utils.FileUtil
import com.ljdemo.lrecorder.utils.ShareFileUtil
import com.ljdemo.lrecorder.utils.VideoInfoListCollections
import com.ljdemo.lrecorder.utils.VideoInfoUtil
import java.io.File
import java.util.Collections

class MainActivity : AppCompatActivity() {

    private lateinit var webView: WebView
    // videoInfo的封面
    private var bitmaps= HashMap<String, Bitmap>()

    companion object{
        private const val permission_request_code=1003
        private val TAG=MainActivity::class.java.simpleName.toString()

        private const val RECORD_REQUEST_CODE = 100
        private var DISPLAY_WIDTH = 720
        private var DISPLAY_HEIGHT = 1280
        private var mScreenDensity = 0
    }

    // 管理屏幕捕捉和录制的框架
    private var mProjectionManager: MediaProjectionManager? = null
    // 录制标志位
    private var isRecording=false
    private var perAlertIsShow=false // 权限被拒绝弹窗是否显示

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        webView = WebView(this)
        // 设置能够执行javascript脚本
        webView.settings.javaScriptEnabled=true
        // 设置js接口，js调用Java方法使用window.android.方法名
        webView.addJavascriptInterface(this@MainActivity, "android")
        // 设置能够使用localStorage存储数据
        webView.settings.domStorageEnabled = true
        //允许webview对文件的操作
//        webView.settings.allowUniversalAccessFromFileURLs=true
        webView.settings.allowFileAccess=true
//        webView.settings.allowFileAccessFromFileURLs=true
        // 设置加载页面
        webView.loadUrl("file:///android_asset/index.html")

        webView.webChromeClient = object : WebChromeClient(){
            override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
                consoleMessage?.let { Log.e(TAG, it.message()) }
                return super.onConsoleMessage(consoleMessage)
            }
        }

        setContentView(webView)

        // 检查权限
        checkPermission()
    }

    override fun onBackPressed() {
        /** 在onBackPressed中实现比较稳定 */
        if (ScreenRecordService.isRecording){
            // 将当前activity放入后台，而非销毁
            moveTaskToBack(true)
            return
        }
        super.onBackPressed()
    }

    @JavascriptInterface
    @RequiresApi(Build.VERSION_CODES.O)
    fun startRecord(){
        // 开始录屏
        mProjectionManager = getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        //开启录制/投射屏幕权限请求弹窗，请求码为 RECORD_REQUEST_CODE
        startActivityForResult(
            mProjectionManager!!.createScreenCaptureIntent(),
            RECORD_REQUEST_CODE
        )
    }

    @JavascriptInterface
    @RequiresApi(api = Build.VERSION_CODES.O)
    fun stopRecord(){
        // 向录屏service发送停止消息
        val service=Intent(this,ScreenRecordService::class.java)
        service.putExtra("type",1)
        startForegroundService(service)
    }

    @JavascriptInterface
    fun checkPermission():Boolean{
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            val permissions = arrayOf(
                Manifest.permission.RECORD_AUDIO,// 录音权限
                Manifest.permission.WRITE_EXTERNAL_STORAGE,// 写文件权限
                Manifest.permission.READ_EXTERNAL_STORAGE,// 读文件权限
                Manifest.permission.FOREGROUND_SERVICE// 前台服务
            )
            for (permission:String in permissions){
                if (ContextCompat.checkSelfPermission(this@MainActivity,permission) != PackageManager.PERMISSION_GRANTED){
                    // 如果没有权限，就申请
                    ActivityCompat.requestPermissions(this,permissions,
                        permission_request_code
                    )
                    return false
                }
            }
        }
        return true
    }

    // 权限被拒绝提示弹窗
    private fun perAlert(){
        if (perAlertIsShow){
            return
        }
        perAlertIsShow=true
        AlertUtil.alert(this,"没有权限","没有权限录屏功能将无法使用","去开启权限","取消",
            { p0, _ -> // 跳转到系统设置该应用的信息页去开启权限
                val intent = Intent()
                intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
                val uri = Uri.fromParts("package", packageName, null)
                intent.data = uri
                startActivityForResult(intent, 200)

                perAlertIsShow=false
                p0?.dismiss()
            }
        ) { p0, _ ->
            perAlertIsShow = false
            p0?.dismiss()
        }
    }

//    override fun onRequestPermissionsResult(
//        requestCode: Int,
//        permissions: Array<String>,
//        grantResults: IntArray
//    ) {
//        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
//
//        // 判断sdk版本大于等于23（android 6），请求码为200
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && requestCode == 200) {
//            for (i in permissions.indices) {
//                // 判断请求的权限用户是否同意
//                // PackageManager.PERMISSION_GRANTED为同意，PackageManager.PERMISSION_DENIED为拒绝
//                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
//                    // 不同意跳转到系统设置该应用的信息页
//                    AlertUtil.alert(this,"权限被拒绝","权限请求被拒绝")
//                    return
//                }
//            }
//        }
//    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == RECORD_REQUEST_CODE){
            if (resultCode != RESULT_OK){
                AlertUtil.showCenterToast(this,"录屏权限被禁止")
                Log.e(TAG,"录屏权限被禁止")
                return
            }

            //获取屏幕宽度，高度和像素密度
            val displayMetrics=resources.displayMetrics
            DISPLAY_WIDTH =displayMetrics.widthPixels
            DISPLAY_HEIGHT =displayMetrics.heightPixels
            mScreenDensity =displayMetrics.densityDpi

            val serIntent=Intent(this,ScreenRecordService::class.java)
            serIntent.putExtra("type", 0)
            serIntent.putExtra("code", resultCode)
            serIntent.putExtra("data", data)
            serIntent.putExtra("density", mScreenDensity)
            serIntent.putExtra("width", DISPLAY_WIDTH)
            serIntent.putExtra("height", DISPLAY_HEIGHT)

            // 从vue中获取是否开启声音录制
            webView.evaluateJavascript("getAudioFlag()") { value ->
                //Log.e("lj----", value!!)

                serIntent.putExtra("audio", value!!.toBoolean())
                startForegroundService(serIntent)

                // 返回桌面
                val homeIntent = Intent(Intent.ACTION_MAIN)
                homeIntent.addCategory(Intent.CATEGORY_HOME)
                startActivity(homeIntent)
            }

        }
    }

    /**
     * 权限请求后回调
     * @param requestCode 请求码
     * @param permissions 请求的权限数组
     * @param grantResults 请求的权限是否同意数组
     */
    @RequiresApi(Build.VERSION_CODES.O)
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String?>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        // Build.VERSION.SDK_INT为动态获取的sdk版本
        // Build.VERSION_CODES.M为固定值24，即android6.0
        // 判断sdk版本大于等于23，请求码为200
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && requestCode == permission_request_code) {

            var flag=true
            for (i in permissions.indices) {
                // 判断请求的权限用户是否同意
                // PackageManager.PERMISSION_GRANTED为同意，PackageManager.PERMISSION_DENIED为拒绝
                if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                    flag=false
                }
            }
            if (!flag){
                // 没有权限，弹窗提示
                perAlert()
            }
        }
    }

    // 跳转到录屏
    @JavascriptInterface
    fun toRecord() {
        val intent=Intent(this@MainActivity,ScreenRecordActivity::class.java)
        startActivity(intent)
    }

    // 跳转到路像
    @JavascriptInterface
    fun toPictureRecord(){
        Log.e("lj---","跳转")
        startActivity(Intent(this@MainActivity,PictureRecordActivity::class.java))
    }

    // 跳转到视频播放
    @JavascriptInterface
    fun toPlayVideo(videoFullName:String){
        val intent=Intent(this@MainActivity,VideoPlayerActivity::class.java)
        intent.putExtra("file",videoFullName)
        startActivity(intent)
    }

    // 获取视频文件信息列表
    @JavascriptInterface
    fun getVideoInfoList(): String? {
        // 获取应用内部目录
        val dir = getExternalFilesDir(Environment.DIRECTORY_MOVIES).toString() + File.separator
        getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        // 获取视频文件列表
        val fileList=FileUtil.getFilesByFolderPath(dir)
        // 获取视频文件信息列表
        val videoInfoList=VideoInfoUtil.getVideoInfoList(fileList)

        // 排序
        Collections.sort(videoInfoList,VideoInfoListCollections())

        // 将bitmap对象提取出来存入 bitmaps，另起一个方法输出图片（转成base64的字符串）
        for(vInfo:VideoInfo in videoInfoList){
            // 放入bitmaps，key为fileName
            bitmaps.put(vInfo.fileName,vInfo.cover)
            // 清空封面属性
            vInfo.cover=null
        }

        // 转换为JSON
        val gson = Gson()
        val jsonArr=gson.toJson(videoInfoList)

        // 获取完信息，清除链表以节约内存
        fileList.clear()
        videoInfoList.clear()

        return jsonArr
    }

    // 获取封面
    @JavascriptInterface
    fun getCover(fileName: String): String {
        var bitmap = bitmaps[fileName]
        return FileUtil.bitmapToBase64(bitmap)
    }

    // 导出文件
    @JavascriptInterface
    fun exportFile(fileFullName:String){
        // 获取Movies文件夹
        val moviesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).toString() + File.separator
        // 复制到Movies文件夹
        FileUtil.copyFile(fileFullName,moviesDir)

        // 映射到系统，TODO 似乎没效果
        val contentValues: ContentValues? = getVideoContentValues(
            File(moviesDir + fileFullName),
            System.currentTimeMillis()
        )
        val uri = contentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,contentValues)
        sendBroadcast(
            Intent(
                Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,uri)
        )

        // 消息通知
        AlertUtil.showCenterToast(this,"导出到Movies文件夹")
    }

    private fun getVideoContentValues(paramFile: File, paramLong: Long): ContentValues? {
        val localContentValues = ContentValues()
        localContentValues.put("title", paramFile.name)
        localContentValues.put("_display_name", paramFile.name)
        localContentValues.put("mime_type", "video/mp4")
        localContentValues.put("datetaken", java.lang.Long.valueOf(paramLong))
        localContentValues.put("date_modified", java.lang.Long.valueOf(paramLong))
        localContentValues.put("date_added", java.lang.Long.valueOf(paramLong))
        localContentValues.put("_data", paramFile.absolutePath)
        localContentValues.put("_size", java.lang.Long.valueOf(paramFile.length()))
        return localContentValues
    }

    // 删除文件
    @JavascriptInterface
    fun delFile(fileFullName:String){
        // 删除文件
        FileUtil.delFile(fileFullName)

        // 删除保存的封面
        val fileName=fileFullName.substringAfterLast(File.separator)
        bitmaps.remove(fileName)

        if (AppUtil.isFastClick()){
            return
        }
        AlertUtil.showCenterToast(this,"删除成功")
    }

    // 分享文件
    @JavascriptInterface
    fun shareFile(fileFullName: String){
        ShareFileUtil.shareVideo(this,fileFullName)
    }

    // 导出应用图标
    @JavascriptInterface
    fun getIcon(): String {
        val drawable = ResourcesCompat.getDrawable(resources, R.mipmap.icon, null)
        val bmp = (drawable as BitmapDrawable).bitmap
        return FileUtil.bitmapToBase64(bmp)
    }

    // 应用信息
    @JavascriptInterface
    fun getAppInfo(): String{
        // 获取版本名
        val packageInfo = packageManager.getPackageInfo(packageName,0)
        val versionName=packageInfo.versionName
        // 获取应用名
        val appName=resources.getString(R.string.app_name)

        return "{" +
                "\"app_version\":\""+ versionName + "\"," +
                "\"app_name\":\"" + appName + "\"" +
                "}"
    }

    override fun onDestroy() {
        // 销毁时清除保存的封面
        bitmaps.clear()
        super.onDestroy()
    }

}